大家好,我是韋恩,今天是鐵人賽的第二十九天,今天我們會來練習language命名空間下的api,使用它幫使用者產生snippet。
在vscode的language命名空間的方法底下,有非常多的方法讓我們增強editor的功能,今天我們就會實際來練習註冊vscode的CompletionItemProvider,產生editor的自動補全提示,讓按下提示的使用者在編輯器上產生程式碼片段。
如上圖所示,在我們註冊使用CompletionItemProvider時,我們會先指定一個vscode.DocumentSelector,然後提供CompletionItemProvider。
DocumentSelector是做什麼用的呢?如英文字面的意思,selector讓我們可以指定某種語言的檔案,並且只對該檔案生成snippet,selector的功能真的是非常方便。
當我們想要對某種語言註冊CompletionItemProvider,比如typescript的檔案,我們就可以這麼設定selector物件
{ language: 'typescript' }
在上面,我們透過指令language_id來選擇語言。
現在我們有了更近一步的需求:我們想讓某一種格式開頭的檔案才套用設定,這個時候可以這樣指定
{ scheme: 'file', pattern: '**/interface.ts', language: 'typescript' }
如上所示,當我們這樣寫,vscode就會在符合pattern屬性裡glob語法的檔案註冊我們的provider,也就是說只有該命名開頭的檔案才會套用服務。
到這裡,讀者應該逐漸感受到了language底下功能的強大了吧!
現在,讓我們來實作provider吧!
class CompletionProvider implements vscode.CompletionItemProvider<vscode.CompletionItem> {
constructor(private completionItems: vscode.CompletionItem[]) {}
provideCompletionItems(
_document: vscode.TextDocument,
_position: vscode.Position,
_token: vscode.CancellationToken,
_context: vscode.CompletionContext
): vscode.ProviderResult<vscode.CompletionItem[] | vscode.CompletionList<vscode.CompletionItem>> {
return this.completionItems;
}
}
在我們指定要實作interface以後,我們至少要在class實作provideCompletionItem的方法,在方法下回傳一個completionItems的vscode.CompletionItem陣列。
因此,讓我們看一下最基本的CompletionItem用法吧!
export interface SnippetSetting {
...
prefix: string;
body: string[];
description: string;
}
const completionItem = (snippet: SnippetSetting) => {
const item = new vscode.CompletionItem(snippet.prefix);
item.insertText = new vscode.SnippetString(snippet.body.join('\n'));
item.documentation = snippet.description;
return item;
};
如上面可見,我們可以將prefix、description以及snippet設定的body分別指派給label、insertText以及documentation的屬性。
當這些item提供給provider並且註冊指定語言檔案,就會產生snippet的提示。
好的,今天我們練習了snippet的用法,明天會繼續實作跟介紹api用法到第三十天,先為賽程做個總結。
之後視情況增補附錄的章節,我們明天見,掰掰。